Geospatial Data Science in Python
  • Syllabus
  • Schedule
    • Section 401
    • Section 402
  • Content
  • Assignments
    • Overview
    • Section 401
    • Section 402
  • Resources
  • GitHub
  • Canvas
  • Ed Discussion

Week 5A: More Geospatial Analysis: Urban Networks

  • Monday, October 2, 2023
  • Section 401
# The usual imports
import altair as alt
import geopandas as gpd
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
# Show all columns in dataframes
pd.options.display.max_columns = 999
# Hide warnings due to issue in shapely package 
# See: https://github.com/shapely/shapely/issues/1345
np.seterr(invalid="ignore");

Today: Urban street networks and OpenStreetMap (OSM)

  • Two tools that make working with OSM data very easy
  • What kind of questions can we answer?
    • Street orientations
    • Mapping event points to streets: car crashes
    • Mapping amenities
    • Network-constrained distances: accessibility

OSM: what is it?

  • Collaborative mapping
  • A free editable map of the World
  • Sort of like Wikipedia for maps

Great source of data: street networks and a wealth of amenity information

https://www.openstreetmap.org

Working with OSM data

  • Raw data is very messy
  • Two relatively new, amazing Python packages greatly simply the process
  • Related, but complementary features
    • OSMnx: downloading and manipulating streets as networks
    • Pandana: networks focused on accessibility of amenities

Related: interactive web maps in Python

Part 1: OSMnx

Relatively new package (just a few years old), but quickly becoming the go to package for working with street networks and OpenStreetMap data in Python.

Several key features:

  • Downloading political boundaries for cities, states, countries, etc

  • Downloading street networks

  • Analyzing networks: routing, visualization, statistics

    • GitHub
    • Introductory Blog Post
    • Jupyter Notebook Examples (Binder)
    • Documentation
import osmnx as ox

1.1. Getting boundary shapefiles from OSM

Key function: geocode_to_gdf() (docs)

We can get the boundary for anything identified as a “place” by OSM.

Important: Be careful to pass the right place name that OSM needs

philly = ox.geocode_to_gdf("Philadelphia, PA")
philly.head()
geometry bbox_north bbox_south bbox_east bbox_west place_id osm_type osm_id lat lon class type place_rank importance addresstype name display_name
0 POLYGON ((-75.28030 39.97500, -75.28022 39.974... 40.137959 39.867005 -74.955831 -75.280298 14128726 relation 188022 39.952724 -75.163526 boundary administrative 16 0.713797 city Philadelphia Philadelphia, Pennsylvania, United States
philly.crs
<Geographic 2D CRS: EPSG:4326>
Name: WGS 84
Axis Info [ellipsoidal]:
- Lat[north]: Geodetic latitude (degree)
- Lon[east]: Geodetic longitude (degree)
Area of Use:
- name: World.
- bounds: (-180.0, -90.0, 180.0, 90.0)
Datum: World Geodetic System 1984 ensemble
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich

We can plot it just like any other GeoDataFrame

# Project it to Web Mercator first and plot
ax = philly.to_crs(epsg=3857).plot(facecolor="none", edgecolor="black")
ax.set_axis_off()

1.2 Projecting with OSMnx

Key function: project_gdf() (docs)

Automatically projects to the Universal Transverse Mercator (UTM) CRS for the UTM zone that the centroid of the polygon lies in

A good, general projection that works for most latitudes except very northern locations.

ax = ox.project_gdf(philly).plot(fc="lightblue", ec="gray")
ax.set_axis_off()

Some more examples:

# Some examples
place1 = ox.geocode_to_gdf("Manhattan, New York City, New York, USA")
place2 = ox.geocode_to_gdf("Miami-Dade County, Florida")
place3 = ox.geocode_to_gdf("Florida, USA")
place4 = ox.geocode_to_gdf("Spain")
# Manhattan
ax = ox.project_gdf(place1).plot(fc="lightblue", ec="gray")
ax.set_axis_off()

# Miami-Dade County
ax = ox.project_gdf(place2).plot(fc="lightblue", ec="gray")
ax.set_axis_off()

# Florida
ax = ox.project_gdf(place3).plot(fc="lightblue", ec="gray")
ax.set_axis_off()

# Spain
ax = ox.project_gdf(place4).plot(fc="lightblue", ec="gray")
ax.set_axis_off()

1.3 Downloading OSM features

Key functions: features_from_*

  • features_from_place() (docs)
    • Download features within an OSM place boundary
  • features_from_address() (docs)
    • Download features within a certain distance of an address
  • features_from_bbox() (docs)
    • Download features within a N, S, E, W bounding box
  • features_from_point() (docs)
    • Download features within a certain distance of a specified point
  • features_from_polygon() (docs)
    • Download features within a polygon object
About OSM features

Important reference: https://wiki.openstreetmap.org/wiki/Map_Features

  • OSM uses a tagging system to categorize different map features
  • The main feature categories are available on the OSM Wikipedia
    • Examples: ‘amenity’, ‘building’, ‘landuse’, ‘highway’
  • There are specific sub-categories for each feature type too:
    • Amenity examples: ‘bar’, ‘college’, ‘library’

In the language of OSM, the “key” is the main feature category (e.g., amenity) and the “value” is the sub-category type (e.g., “bar”)

osmnx mirrors the key/value syntax of OSM. Use a dict to specify the features you want:

# Get all amenities in Philadelphia
amenities = ox.features_from_place("Philadelphia, PA", tags={"amenity": True})
len(amenities)
10647
amenities.head()
geometry amenity created_by cuisine name brand brand:wikidata brand:wikipedia operator operator:wikidata operator:wikipedia short_name addr:city addr:housenumber addr:postcode addr:state addr:street contact:website official_name opening_hours phone takeaway source wheelchair healthcare internet_access url contact:phone description email website wikidata internet_access:ssid brewery alt_name ele gnis:county_id gnis:created gnis:feature_id gnis:state_id religion historic:amenity old_name denomination building comment operator:type school wikipedia gnis:edited check_date craft microbrewery restaurant contact:facebook name:en social_facility operator:short emergency healthcare:speciality bicycle_parking capacity covered barrier atm attraction gnis:county_name gnis:import_uuid gnis:reviewed internet_access:fee addr:county addr:country outdoor_seating artist_name artwork_subject artwork_type image start_date statue subject:wikidata tourism reservation website:menu air_conditioning shop training toilets:wheelchair addr:housename bottle parking designation not:brand:wikidata dispensing drive_through screen delivery diet:vegan payment:cash payment:coins indoor_seating smoking architect contact:instagram collection_times ref male female fee diet:vegetarian fax bar source:pkey fixme access changing_table toilets name:zh addr:full entrance level name:he fuel:biodiesel fuel:biogas fuel:cng fuel:diesel fuel:e10 fuel:e85 fuel:electricity sport wifi collection_times:signed ref:signed drive_in check_date:collection_times food toilets:access payment:bitcoin diet:halal disused:amenity branch self_service diet:meat note leisure drink:club-mate car_wash compressed_air toilets:disposal unisex contact:twitter currency:XBT diet:pescetarian lgbtq payment:credit_cards payment:debit_cards park_ride supervised check_date:opening_hours opening_hours:signed landuse flickr contact:email facebook instagram service_times twitter youtube source:cuisine social_facility:for disused:shop toilets:position maxheight wheelchair:description wheelchair:description:en layer service:bicycle:chain_tool service:bicycle:pump currency:USD drink:coca-cola drink:coke drink:cola drink:cola_zero drink:soda drink:water vending opening_hours:kitchen bicycle_rental network network:wikidata network:wikipedia amenity_1 recycling:computers recycling:tv_monitor recycling_type ferry public_transport toilets:unisex kitchen_hours animal addr:unit was:amenity was:cuisine was:delivery was:drive_through was:name was:outdoor_seating was:takeaway direction backrest service:bicycle:repair payment:cards name:es diet:kosher theatre:genre service:bicycle:tools beds payment:visa cash_in currency:BCH currency:LTC office date display faces studio name:ca bench lit shelter_type addr:city:ar name:ar colour material fountain addr:block_number seats brand:type indoor parcel_locker:type parcel_mail_in parcel_pickup historic type payment:american_express payment:discover_card payment:mastercard dog recycling:beverage_cartons recycling:cans recycling:glass_bottles recycling:paper recycling:plastic recycling:plastic_bottles recycling:plastic_packaging portable toilets:handwashing opening_hours:drive_through internet_access:description name:vi payment:cheque min_age bus tram waste payment:cash_app payment:venmo seating street_vendor theatre:type smoothness surface brand:en brand:zh location drinking_water height fridge wikimedia_commons opening_hours:covid19 diet:healthy abandoned:amenity memorial payment:lightning payment:lightning_contactless payment:onchain country payment:contactless delivery:partner internet_access:password post_box:type description:en inscription check_date:currency:XBT public_bookcase:type urgent_care diet:gluten_free community_centre:for community_centre animal_shelter name:etymology name:etymology:wikidata mobile nodes building:levels capacity:disabled building:floor ref:nrhp vehicle natural water building:use ship:type roof:shape automated brand:website building:material source:name roof:levels roof:material access:conditional rite heritage heritage:operator architect:wikidata building:levels:underground heritage:website nrhp:criteria nrhp:inscription_date building:colour area check_date:compressed_air gnis:fcode nonsquare name:ja name:zn roof:orientation happy_hours building:part elevation historic:name grades maxstay monastery:type library theme owner loc_name drink bin police school:type old_name1 old_name2 fuel:octane_95 fuel:gasoline fuel:octane_87 healthcare:counselling orientation parking:orientation protection_title source_ref parking_space ways healthcare:for
element_type osmid
node 109811385 POINT (-75.19487 40.05846) bench NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
274215467 POINT (-75.19492 39.95935) fast_food Potlatch 0.9c pizza Powelton Pizza NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
274216093 POINT (-75.19125 39.95764) atm NaN NaN Citibank Citibank Q857063 en:Citibank Citibank Q857063 en:Citibank Citi NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
274217596 POINT (-75.19229 39.95301) cafe NaN coffee_shop Starbucks Starbucks Q37158 en:Starbucks NaN NaN NaN NaN Philadelphia 3401 19104 PA Walnut Street https://www.starbucks.com/store-locator/store/... Starbucks Coffee Mo-Fr 05:30-24:00; Sa,Su 06:00-24:00 215-387-1914 yes NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
313440966 POINT (-75.16694 39.96394) car_sharing Potlatch 0.10f NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN local_knowledge NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
# Get all bars in philadelphia
bars = ox.features_from_place("Philadelphia, PA", tags={"amenity": "bar"})
len(bars)
165
bars.head()
addr:city addr:housenumber addr:postcode addr:state addr:street amenity brewery craft gnis:county_id microbrewery name operator restaurant website wikidata wikipedia geometry contact:phone contact:website description opening_hours outdoor_seating check_date contact:facebook phone air_conditioning smoking toilets:wheelchair wheelchair indoor_seating designation addr:housename source wifi leisure sport cuisine diet:vegan diet:vegetarian food internet_access brand brand:wikidata wheelchair:description fixme name:en name:es addr:unit check_date:opening_hours email min_age alt_name level height opening_hours:signed nodes atm building building:levels nonsquare heritage
element_type osmid
node 357303425 Philadelphia 500 19123 PA Spring Garden Street bar yes brewery 101 yes Yards Brewing Company Yards Brewing Company yes https://yardsbrewing.com/ Q16903914 en:Yards Brewing Company POINT (-75.14712 39.96067) NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
655425272 NaN NaN NaN NaN NaN bar NaN NaN NaN NaN Drinkers West NaN NaN NaN NaN NaN POINT (-75.20020 39.95521) NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1033935437 NaN 2101 NaN NaN Chestnut Street bar NaN NaN NaN NaN Mix Bar & Grill NaN NaN NaN NaN NaN POINT (-75.17552 39.95242) +1 215-568-3355 https://mixbarandgrillphilly.com/location/mix-... The bar is open until whenever the rush ends. Mo-We,Su 11:00-22:00; Th-Sa 11:00-23:00 yes NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1167079387 NaN 401 NaN NaN South Street bar NaN NaN NaN NaN MilkBoy South Street NaN NaN NaN NaN NaN POINT (-75.14925 39.94170) +1 215-925-6455 https://www.milkboy.tv/southstreet NaN Mo-Tu,Su 11:00-24:00; We-Sa 11:00-25:00 NaN 2023-04-12 https://www.facebook.com/milkboysouthstreet NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1204761128 NaN NaN NaN NaN NaN bar NaN NaN NaN NaN Vikings High School Club NaN NaN NaN NaN NaN POINT (-75.16363 39.92685) NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
# Get bar, pub, and restaurant features in Philadelphia
food_and_drink = ox.features_from_place(
    "Philadelphia, PA", tags={"amenity": ["pub", "bar", "restaurant"]}
)
len(food_and_drink)
1075
food_and_drink.head()
amenity created_by name source wheelchair geometry addr:city addr:housenumber addr:postcode addr:state addr:street brewery opening_hours craft gnis:county_id microbrewery operator restaurant website wikidata wikipedia cuisine outdoor_seating brand brand:wikidata check_date contact:facebook contact:website email phone reservation website:menu description designation not:brand:wikidata contact:phone contact:instagram internet_access diet:vegan diet:vegetarian fax air_conditioning smoking bar takeaway addr:housename toilets:wheelchair addr:country alt_name short_name name:zh level indoor_seating sport wifi delivery drive_in payment:cash food payment:bitcoin diet:halal disused:amenity brand:wikipedia official_name diet:meat capacity note leisure contact:twitter currency:XBT fixme diet:pescetarian lgbtq payment:credit_cards payment:debit_cards branch source:cuisine wheelchair:description facebook opening_hours:kitchen ref amenity_1 kitchen_hours name:en name:es addr:unit check_date:opening_hours name:ca internet_access:fee toilets payment:american_express payment:discover_card payment:mastercard payment:visa start_date internet_access:description internet_access:ssid min_age diet:healthy drive_through country delivery:partner toilets:access height payment:contactless opening_hours:signed diet:gluten_free nodes building historic payment:cards ship:type atm building:levels area image roof:levels name:ja name:zn happy_hours nonsquare theme heritage layer
element_type osmid
node 333786044 restaurant Potlatch 0.10f Sam's Morning Glory knowledge limited POINT (-75.15893 39.94086) NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
343293806 pub NaN Prohibition Taproom survey NaN POINT (-75.15946 39.96073) Philadelphia 501 19123 PA North 13th Street yes Mo-Su 11:00-02:00 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
357303425 bar NaN Yards Brewing Company NaN NaN POINT (-75.14712 39.96067) Philadelphia 500 19123 PA Spring Garden Street yes NaN brewery 101 yes Yards Brewing Company yes https://yardsbrewing.com/ Q16903914 en:Yards Brewing Company NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
566683522 restaurant NaN Spring Garden Pizza & Restaurant NaN NaN POINT (-75.15755 39.96205) NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN pizza NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
596230881 restaurant NaN NaN NaN NaN POINT (-75.18682 40.05492) NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
# Get bus stop features
bus_stops = ox.features_from_place("Philadelphia, PA", tags={"highway": "bus_stop"})
len(bus_stops)
290
bus_stops.head()
bench bus covered highway name network network:wikidata operator public_transport shelter geometry network:wikipedia ref tactile_paving wheelchair route_ref local_ref designation source bin lit departures_board internet_access addr:street route_ref_1 description note operator:wikidata brand brand:wikidata railway tram trolleybus network:short not:network:wikidata
element_type osmid
node 361011456 yes yes yes bus_stop 13th St & Market St SEPTA Q2037863 SEPTA platform yes POINT (-75.16166 39.95223) NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
750281693 NaN yes NaN bus_stop NaN NaN NaN NaN platform NaN POINT (-75.07732 40.01797) NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
768271130 NaN yes NaN bus_stop Wissahickon Transportation Center SEPTA Q2037863 SEPTA platform yes POINT (-75.20726 40.01487) NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1015342921 NaN yes NaN bus_stop NaN NaN NaN NaN platform NaN POINT (-75.18187 39.96640) NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1015342926 NaN yes NaN bus_stop NaN NaN NaN NaN platform NaN POINT (-75.18024 39.96670) NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
# Get commercial and retail landuse features
landuse = ox.features_from_place(
    "Philadelphia, PA", tags={"landuse": ["commercial", "retail"]}
)
len(landuse)
349

Let’s plot the land use features:

fig, ax = plt.subplots(figsize=(10, 6))

ax = landuse.plot(ax=ax)
ax.set_axis_off()

1.4 Downloading street networks

Key functions: graph_from_*

  • graph_from_place() (docs)
    • Download street network within an OSM place boundary
  • graph_from_address() (docs)
    • Download street network within a certain distance of an address
  • graph_from_bbox() (docs)
    • Download street network within a N, S, E, W bounding box
  • graph_from_point() (docs)
    • Download street network within a certain distance of a specified point
  • graph_from_polygon() (docs)
    • Download street network within a polygon object

Street network around an address

Get streets within 500 meters of the center of Center City

G = ox.graph_from_address("Center City, Philadelphia, PA", dist=500)

Project and plot it:

G_projected = ox.project_graph(G)
ox.plot_graph(G_projected);

Remove the nodes:

ox.plot_graph(G_projected, node_size=0);

Let’s zoom out to 2,000 meters. This will take a little longer.

G = ox.graph_from_address("Center City, Philadelphia, PA", dist=2000)
G_projected = ox.project_graph(G)
ox.plot_graph(G_projected, node_size=0);

Getting different network types

  • drive - get drivable public streets (but not service roads)
  • drive_service - get drivable streets, including service roads
  • walk - get all streets and paths that pedestrians can use (this network type ignores one-way directionality)
  • bike - get all streets and paths that cyclists can use
  • all - download all non-private OSM streets and paths
  • all_private - download all OSM streets and paths, including private-access ones (default)
# the "drive" network
G = ox.graph_from_address("Center City, Philadelphia, PA", network_type="drive")
ox.plot_graph(G);

# the "walk" network
G = ox.graph_from_address("Center City, Philadelphia, PA", network_type="walk")
ox.plot_graph(ox.project_graph(G));

Street network within a place boundary

Use graph_from_place() to get the streets within a specific OSM place.

Caution

A couple of things to watch out for: 1. The place query has to be resolved by OSM. 2. If the place is a big city, you might be downloading a lot of data!

Let’s check out the street network for Berkeley, CA:

berkeley = ox.graph_from_place("Berkeley, California, USA")
ox.plot_graph(ox.project_graph(berkeley), node_size=0);

Streets within a specific polygon

Example: Let’s download all streets within Center City. We will use the “Central” planning district as a proxy for this area. The city’s planning districts are available on Open Data Philly.

planning_districts = gpd.read_file(
    "https://opendata.arcgis.com/datasets/0960ea0f38f44146bb562f2b212075aa_0.geojson"
)
planning_districts.head()
OBJECTID_1 OBJECTID DIST_NAME ABBREV Shape__Area Shape__Length PlanningDist DaytimePop geometry
0 1 14 River Wards RW 2.107270e+08 66931.595020 NaN NaN POLYGON ((-75.09798 40.00496, -75.09687 40.005...
1 2 3 North Delaware NDEL 2.700915e+08 89213.074378 NaN NaN POLYGON ((-74.98159 40.05363, -74.98139 40.053...
2 3 0 Lower Far Northeast LFNE 3.068529e+08 92703.285159 NaN NaN POLYGON ((-74.96443 40.11728, -74.96434 40.117...
3 4 9 Central CTR 1.782880e+08 71405.143450 NaN NaN POLYGON ((-75.14791 39.96733, -75.14715 39.967...
4 5 10 University Southwest USW 1.296468e+08 65267.676141 NaN NaN POLYGON ((-75.18742 39.96338, -75.18644 39.963...

Trim to the central district:

central_district = planning_districts.query("DIST_NAME == 'Central'")

And plot it:

ax = ox.project_gdf(central_district).plot(fc="lightblue", ec="gray")
ax.set_axis_off()

Squeeze it so we can get the geometry polygon:

center_city_outline = central_district.squeeze().geometry

center_city_outline

Now, let’s use ox.graph_from_polygon() to extract streets within this polygon.

# Get the graph
G_cc = ox.graph_from_polygon(center_city_outline, network_type="drive")
# Viola!
ox.plot_graph(ox.project_graph(G_cc), node_size=0);

1.5 Converting from a graph to a GeoDataFrame

Key function: ox.graph_to_gdfs() (docs)

You can get a GeoDataFrame for both the nodes (points) and edges (lines)

type(G_cc)
networkx.classes.multidigraph.MultiDiGraph
# only get the edges
cc_edges = ox.graph_to_gdfs(G_cc, edges=True, nodes=False)
# we have lots of data associated with each edge!
cc_edges.head()
osmid oneway name highway reversed length geometry maxspeed lanes bridge ref tunnel width service access junction
u v key
109727439 109911666 0 132508434 True Bainbridge Street residential False 44.137 LINESTRING (-75.17104 39.94345, -75.17053 39.9... NaN NaN NaN NaN NaN NaN NaN NaN NaN
109727448 109727439 0 12109011 True South Colorado Street residential False 109.484 LINESTRING (-75.17125 39.94248, -75.17120 39.9... NaN NaN NaN NaN NaN NaN NaN NaN NaN
110034229 0 12159387 True Fitzwater Street residential False 91.353 LINESTRING (-75.17125 39.94248, -75.17137 39.9... NaN NaN NaN NaN NaN NaN NaN NaN NaN
109727507 110024052 0 193364514 True Carpenter Street residential False 53.208 LINESTRING (-75.17196 39.93973, -75.17134 39.9... NaN NaN NaN NaN NaN NaN NaN NaN NaN
109728761 110274344 0 672312336 True Brown Street residential False 58.270 LINESTRING (-75.17317 39.96951, -75.17250 39.9... 25 mph NaN NaN NaN NaN NaN NaN NaN NaN
# plot it like any old GeoDataFrame
ax = cc_edges.to_crs(epsg=3857).plot(color="gray")

# add the neighborhood boundaries
boundary = gpd.GeoSeries([center_city_outline], crs="EPSG:4326")
boundary.to_crs(epsg=3857).plot(
    ax=ax, facecolor="none", edgecolor="red", linewidth=3, zorder=2
)

ax.set_axis_off()

Don’t forget: We can use the .explore() function to get an interactive web map via Folium:

cc_edges.explore(tiles='cartodb positron')
Make this Notebook Trusted to load map: File -> Trust Notebook

1.6 What can we do with the graph?

  • Network-based statistics
  • Routing
  • Street orientations
  • Visualizing crashes

And much more: see the OSMnx repository of Jupyter notebook examples

Street orientations

A great blog post on street orientations across different US and global cities.

One of my favorite examples of data viz, using matplotlib for radial histograms of street orientations…

The code for these histograms is available in the osmnx examples repository.

Network statistics

We can use the ox.basic_stats() to get some basic network statistics

ox.basic_stats(G_cc)
{'n': 2026,
 'm': 3902,
 'k_avg': 3.8519249753208293,
 'edge_length_total': 349745.43700000027,
 'edge_length_avg': 89.63235187083554,
 'streets_per_node_avg': 3.428923988153998,
 'streets_per_node_counts': {0: 0, 1: 55, 2: 9, 3: 996, 4: 948, 5: 14, 6: 4},
 'streets_per_node_proportions': {0: 0.0,
  1: 0.027147087857847977,
  2: 0.004442250740375123,
  3: 0.491609081934847,
  4: 0.46791707798617965,
  5: 0.006910167818361303,
  6: 0.0019743336623889436},
 'intersection_count': 1971,
 'street_length_total': 306400.7959999999,
 'street_segment_count': 3384,
 'street_length_avg': 90.54397044917255,
 'circuity_avg': 1.0172703832466288,
 'self_loop_proportion': 0.0008865248226950354}

Finding the shortest route

Let’s calculate the shortest route between the Art Museum and the Liberty Bell.

We’ll need to download all amenities in Philadelphia of type “tourism”.

  • The ox.features_from_place() can download OSM features with a specific tag
  • You can consult the OSM pages (the Art Museum and Liberty Bell) for each feature for additional info
  • Both features are categorized as “tourism” in the OSM data — use the “tags” keyword to select this category
philly_tourism = ox.features_from_place("Philadelphia, PA", tags={"tourism": True})
len(philly_tourism)
593
philly_tourism.head()
ref geometry ele gnis:county_id gnis:created gnis:feature_id gnis:state_id name tourism brand brand:wikidata brand:wikipedia operator artwork_type historic source wikidata information artist_name material website addr:state gnis:county_name gnis:reviewed gnis:import_uuid fee opening_hours amenity artwork_subject image start_date statue subject:wikidata colour wheelchair wikipedia addr:city name:de designation description museum operator:type alt_name barrier heritage heritage:operator heritage:website nrhp:criteria nrhp:inscription_date nrhp:nhl protection_title ref:nrhp source_ref artist:wikidata height name:fr addr:housenumber addr:postcode addr:street memorial year_of_construction name:ru layer phone check_date contact:email name:en board_type toilets:wheelchair inscription subject:wikipedia level natural attraction note display end_date comment historic:amenity garden:type leisure postal_code official_name internet_access short_name parking guest_house inscription:url gender bicycle hiking covered drinking_water openfire addr:unit mimics source:url direction email departures_board map_size map_type direction_north direction_southeast direction_west direction_east direction_south direction_northeast direction_northwest direction_southwest nodes building building:material name:hi building:levels roof:shape highway incline step_count building:wikidata building:wikipedia check_date:opening_hours old_name smoking building:colour air_conditioning fax rooms stars roof:colour addr:country contact:fax contact:phone ship:type addr:housename bar disused:amenity roof:material internet_access:fee abandoned:amenity fixme internet_access:ssid fee:conditional shop roof:levels name:zh artist:website bridge foot horse lit sac_scale surface trail_visibility width bridge:structure man_made disused:website boundary operator:short operator:wikidata ownership protected building:part area subject contact:facebook ways type place
element_type osmid
node 357371322 NaN POINT (-75.19580 39.96970) 17 101 08/23/2007 2347097 42 Bird Lake Picnic Area picnic_site NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
360500844 NaN POINT (-75.19582 39.95352) NaN NaN NaN NaN NaN Hilton Inn at Penn hotel Hilton Q598884 en:Hilton Hotels & Resorts Hilton NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
360515304 NaN POINT (-75.14860 39.94771) NaN NaN NaN NaN NaN Robert Morris artwork NaN NaN NaN NaN statue memorial survey NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
360542779 NaN POINT (-75.18932 39.95540) NaN NaN NaN NaN NaN Mario the Magnificent artwork NaN NaN NaN NaN statue NaN NaN Q98563440 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
360777728 NaN POINT (-75.19021 39.95230) NaN NaN NaN NaN NaN Pennsylvania Historical Marker: ENIAC, first a... information NaN NaN NaN NaN NaN NaN NaN NaN board NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
# How to find the name of the POI: search for keywords
philly_tourism.loc[philly_tourism['name'].str.contains("Art", na=False)]
ref geometry ele gnis:county_id gnis:created gnis:feature_id gnis:state_id name tourism brand brand:wikidata brand:wikipedia operator artwork_type historic source wikidata information artist_name material website addr:state gnis:county_name gnis:reviewed gnis:import_uuid fee opening_hours amenity artwork_subject image start_date statue subject:wikidata colour wheelchair wikipedia addr:city name:de designation description museum operator:type alt_name barrier heritage heritage:operator heritage:website nrhp:criteria nrhp:inscription_date nrhp:nhl protection_title ref:nrhp source_ref artist:wikidata height name:fr addr:housenumber addr:postcode addr:street memorial year_of_construction name:ru layer phone check_date contact:email name:en board_type toilets:wheelchair inscription subject:wikipedia level natural attraction note display end_date comment historic:amenity garden:type leisure postal_code official_name internet_access short_name parking guest_house inscription:url gender bicycle hiking covered drinking_water openfire addr:unit mimics source:url direction email departures_board map_size map_type direction_north direction_southeast direction_west direction_east direction_south direction_northeast direction_northwest direction_southwest nodes building building:material name:hi building:levels roof:shape highway incline step_count building:wikidata building:wikipedia check_date:opening_hours old_name smoking building:colour air_conditioning fax rooms stars roof:colour addr:country contact:fax contact:phone ship:type addr:housename bar disused:amenity roof:material internet_access:fee abandoned:amenity fixme internet_access:ssid fee:conditional shop roof:levels name:zh artist:website bridge foot horse lit sac_scale surface trail_visibility width bridge:structure man_made disused:website boundary operator:short operator:wikidata ownership protected building:part area subject contact:facebook ways type place
element_type osmid
node 367974278 NaN POINT (-75.15240 40.03748) 61 NaN NaN 2349240 NaN La Salle University Art Museum museum NaN NaN NaN NaN NaN NaN USGS Geonames Q16893816 NaN NaN NaN https://artcollection.lasalle.edu/ PA Philadelphia no NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
4064343335 NaN POINT (-75.22113 40.02427) NaN NaN NaN NaN NaN Soft Illusions Fine Art Gallery gallery NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN http://www.softillusions.net/ PA NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN Philadelphia NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 4226 19127 Main Street NaN NaN NaN NaN +1 215-840-0832 2023-08-08 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
5368454121 NaN POINT (-75.19477 39.95406) NaN NaN NaN NaN NaN Institute of Contemporary Art museum NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN https://icaphila.org/ PA NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN yes NaN Philadelphia NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 118 19104 South 36th Street NaN NaN NaN NaN NaN NaN NaN NaN NaN yes NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
5718906477 NaN POINT (-75.13058 39.99573) NaN NaN NaN NaN NaN Art Making Machine Studios gallery NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN PA NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN Philadelphia NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 3000 19133 North Hope Street NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
6639391809 NaN POINT (-75.16088 39.96383) NaN NaN NaN NaN NaN Philadelphia Museum of Jewish Art museum NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN https://rodephshalom.org/community/philadelphi... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
6680708848 NaN POINT (-75.16833 39.94733) NaN NaN NaN NaN NaN Romanian Folk Art Museum museum NaN NaN NaN NaN NaN NaN NaN Q113484178 NaN NaN NaN http://www.romanianculture.us/ PA NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN Philadelphia NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1606 19103 Spruce Street NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
way 28533972 NaN POLYGON ((-75.18116 39.96467, -75.18138 39.964... 32 NaN NaN NaN NaN Philadelphia Museum of Art museum NaN NaN NaN NaN NaN NaN NaN Q510324 NaN NaN NaN https://www.philamuseum.org/ PA NaN NaN NaN NaN Su,Mo,Th,Sa 10:00-17:00; Fr 10:00-20:45 NaN NaN NaN NaN NaN NaN NaN yes en:Philadelphia Museum of Art Philadelphia NaN NaN NaN art NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 2600 19130 Benjamin Franklin Parkway NaN NaN NaN NaN +1-215-763-8100 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN [313440467, 313440468, 313440469, 313440470, 3... yes NaN फिलाडेल्फिया कला संग्रहालय NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
333931830 NaN POLYGON ((-75.16410 39.95543, -75.16416 39.955... 13 NaN NaN 1196718 NaN Pennsylvania Academy of the Fine Arts museum NaN NaN NaN NaN NaN building NaN Q1952033 NaN NaN NaN https://www.pafa.org/ PA NaN NaN NaN NaN Tu-Fr 10:00-17:00; Sa-Su 11:00-17:00 NaN NaN NaN NaN NaN NaN NaN NaN en:Pennsylvania Academy of the Fine Arts Philadelphia NaN NaN NaN art NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 71000731 NaN NaN NaN NaN 118 19102 North Broad Street NaN NaN NaN NaN +1-215-972-7600 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN [3409804705, 3409804706, 3453181052, 340980470... yes NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN US NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
988345364 NaN POLYGON ((-75.21926 40.08320, -75.21931 40.083... 84 NaN NaN NaN NaN Woodmere Art Museum museum NaN NaN NaN NaN NaN NaN esri/Philadelphia_PA_Buildings_OSM Q2424929 NaN NaN NaN https://woodmereartmuseum.org/ PA NaN NaN NaN yes We-Su 10:00-17:00; Sa 10:00-18:00 NaN NaN NaN NaN NaN NaN NaN yes NaN Philadelphia NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 20.72 NaN 9201 19118 Germantown Avenue NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN [10968493549, 9135569442, 9135569424, 91355694... yes NaN NaN NaN NaN NaN NaN NaN NaN NaN 2023-06-10 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
art_museum = philly_tourism.query("name == 'Philadelphia Museum of Art'").squeeze()

art_museum.geometry

liberty_bell = philly_tourism.query("name == 'Liberty Bell'").squeeze()

liberty_bell.geometry

Now, extract the lat and lng coordinates

For the Art Museum geometry, we can use the .geometry.centroid attribute to calculate the centroid of the building footprint.

liberty_bell_x = liberty_bell.geometry.x
liberty_bell_y = liberty_bell.geometry.y
art_museum_x = art_museum.geometry.centroid.x
art_museum_y = art_museum.geometry.centroid.y

Find the nearest nodes on our OSMnx graph, using the ox.nearest_nodes() function

ox.nearest_nodes?
Signature: ox.nearest_nodes(G, X, Y, return_dist=False)
Docstring:
Find the nearest node to a point or to each of several points.
If `X` and `Y` are single coordinate values, this will return the nearest
node to that point. If `X` and `Y` are lists of coordinate values, this
will return the nearest node to each point.
If the graph is projected, this uses a k-d tree for euclidean nearest
neighbor search, which requires that scipy is installed as an optional
dependency. If it is unprojected, this uses a ball tree for haversine
nearest neighbor search, which requires that scikit-learn is installed as
an optional dependency.
Parameters
----------
G : networkx.MultiDiGraph
    graph in which to find nearest nodes
X : float or list
    points' x (longitude) coordinates, in same CRS/units as graph and
    containing no nulls
Y : float or list
    points' y (latitude) coordinates, in same CRS/units as graph and
    containing no nulls
return_dist : bool
    optionally also return distance between points and nearest nodes
Returns
-------
nn or (nn, dist) : int/list or tuple
    nearest node IDs or optionally a tuple where `dist` contains distances
    between the points and their nearest nodes
File:      ~/mambaforge/envs/musa-550-fall-2023/lib/python3.10/site-packages/osmnx/distance.py
Type:      function
# Get the origin node
orig_node = ox.nearest_nodes(G_cc, liberty_bell_x, liberty_bell_y) 

# Get the destination node
dest_node = ox.nearest_nodes(G_cc, art_museum_x, art_museum_y)

Now, we can use ox.shortest_path() function to find the shortest path between these graph nodes.

Note

We need to specify weight=‘length’ to find the shortest path by minimizing distance traveled (otherwise it treats each edge as weight=1).

# get the shortest path --> just a list of node IDs
route1 = ox.shortest_path(G_cc, orig_node, dest_node, weight="length")

route1
[3408446156,
 110217312,
 109814427,
 5372039288,
 109814445,
 8588123388,
 109814449,
 5358069713,
 5372059864,
 2644235371,
 5534891499,
 110540235,
 109750941,
 110402209,
 110402230,
 534960802,
 110391250,
 637791907,
 637791980,
 110329803,
 110329806,
 775897224,
 3414249481,
 110329822,
 110353061,
 11162290432,
 110054089,
 775897147,
 110329848,
 110329851,
 110125895,
 534969088,
 109745905,
 109740423,
 110330569,
 550175455,
 550175399]

Use ox.plot_graph_route() to plot a graph and highlight a specific route

ox.plot_graph_route(G_cc, route1, node_size=0);

How about an interactive version?

osmnx has a helper function ox.utils_graph.route_to_gdf() to convert a route to a GeoDataFrame of edges.

ox.utils_graph.route_to_gdf(G_cc, route1, weight="length").explore(
    tiles="cartodb positron",
    color="red",
)
Make this Notebook Trusted to load map: File -> Trust Notebook

Finding the shortest travel time

The add_edge_speeds function add edge speeds (km per hour) to graph as new speed_kph edge attributes.

The function will add free-flow travel speeds for all edges based on the average maxspeed value of edges, per highway type. This process can definitely be imprecise, but in the case that you happen to have more precise speed data, you can supply your own data instead of relying on OSM data.

# impute speed on all edges missing data
G_cc = ox.add_edge_speeds(G_cc)

# calculate travel time (seconds) for all edges
G_cc = ox.add_edge_travel_times(G_cc)
# Get the graph edges
edges = ox.graph_to_gdfs(G_cc, nodes=False)
edges.head()
osmid oneway name highway reversed length speed_kph travel_time geometry maxspeed lanes bridge ref tunnel width service access junction
u v key
109727439 109911666 0 132508434 True Bainbridge Street residential False 44.137 37.0 4.3 LINESTRING (-75.17104 39.94345, -75.17053 39.9... NaN NaN NaN NaN NaN NaN NaN NaN NaN
109727448 109727439 0 12109011 True South Colorado Street residential False 109.484 37.0 10.7 LINESTRING (-75.17125 39.94248, -75.17120 39.9... NaN NaN NaN NaN NaN NaN NaN NaN NaN
110034229 0 12159387 True Fitzwater Street residential False 91.353 37.0 8.9 LINESTRING (-75.17125 39.94248, -75.17137 39.9... NaN NaN NaN NaN NaN NaN NaN NaN NaN
109727507 110024052 0 193364514 True Carpenter Street residential False 53.208 37.0 5.2 LINESTRING (-75.17196 39.93973, -75.17134 39.9... NaN NaN NaN NaN NaN NaN NaN NaN NaN
109728761 110274344 0 672312336 True Brown Street residential False 58.270 40.2 5.2 LINESTRING (-75.17317 39.96951, -75.17250 39.9... 25 mph NaN NaN NaN NaN NaN NaN NaN NaN
# Groupby highway type and get the mean values
edges["highway"] = edges["highway"].astype(str)
edges.groupby("highway")[["length", "speed_kph", "travel_time"]].mean()
length speed_kph travel_time
highway
['primary', 'secondary'] 676.801000 44.900000 54.300000
['tertiary', 'motorway_link'] 151.615000 42.100000 13.000000
living_street 52.877143 47.200000 4.028571
motorway 451.723346 83.038462 19.323077
motorway_link 295.568174 47.200000 22.550000
primary 103.286915 44.870944 8.251816
primary_link 56.531789 40.200000 5.063158
residential 81.302576 37.001304 7.920488
secondary 93.164418 43.312000 7.877818
secondary_link 65.884000 47.200000 5.000000
tertiary 80.093234 42.094659 6.867507
tertiary_link 37.969000 47.200000 2.850000
trunk 72.969538 54.507692 4.800000
trunk_link 176.703500 47.200000 13.500000
unclassified 126.344395 32.200000 14.128947
# calculate two routes by minimizing travel time
route2 = ox.shortest_path(G_cc, orig_node, dest_node, weight="travel_time")
# plot the routes
fig, ax = ox.plot_graph_routes(
    G_cc,
    routes=[route1, route2],
    route_colors=["r", "y"],
    route_linewidth=6,
    node_size=0,
)

Let’s plot both in an interactive map:

m = ox.utils_graph.route_to_gdf(G_cc, route1, weight="length").explore(
    tiles="cartodb dark matter",
    color="red",
)

m = ox.utils_graph.route_to_gdf(G_cc, route2, weight="length").explore(
    tiles="cartodb dark matter",
    color="yellow",
    m=m
)

m
Make this Notebook Trusted to load map: File -> Trust Notebook

Let’s compare to the two routes:

Distances:

meters_to_miles = 0.0006213712

# compare the two routes
route1_length = (
    ox.utils_graph.route_to_gdf(G_cc, route1, weight="length")["length"].sum()
    * meters_to_miles
)

route2_length = (
    ox.utils_graph.route_to_gdf(G_cc, route2, weight="length")["length"].sum()
    * meters_to_miles
)

Travel times:

seconds_to_mins = 1.0 / 60

route1_time = (
    ox.utils_graph.route_to_gdf(G_cc, route1, weight="travel_time")["travel_time"].sum()
    * seconds_to_mins
)
route2_time = (
    ox.utils_graph.route_to_gdf(G_cc, route2, weight="travel_time")["travel_time"].sum()
    * seconds_to_mins
)

Summarize:

print(f"Route 1 is {route1_length:.2f} miles and takes {route1_time:.2f} minutes.")
print(f"Route 2 is {route2_length:.2f} miles and takes {route2_time:.2f} minutes.")
Route 1 is 2.19 miles and takes 5.04 minutes.
Route 2 is 2.46 miles and takes 4.46 minutes.

Part 2: Pandana

“Pandas Network Analysis - dataframes of network queries, quickly”

A complementary set of OSM-related features: - Downloading OSM-based networks - Extracting amenity data (so-called “Points of Interest”) - Calculating network-constrained distances

  • GitHub
  • Jupyter Notebook Examples
  • Documentation
import pandana as pnda
from pandana.loaders import osm

Step 1: Get amenity data

Key function: osm.node_query()

  • This will extract amenities within a given bounding box.
  • Similar to the ox.geometries_from_bbox() function in OSMnx, but we slightly different syntax.
osm.node_query?
Signature: osm.node_query(lat_min, lng_min, lat_max, lng_max, tags=None)
Docstring:
Search for OSM nodes within a bounding box that match given tags.
Parameters
----------
lat_min, lng_min, lat_max, lng_max : float
tags : str or list of str, optional
    Node tags that will be used to filter the search.
    See http://wiki.openstreetmap.org/wiki/Overpass_API/Language_Guide
    for information about OSM Overpass queries
    and http://wiki.openstreetmap.org/wiki/Map_Features
    for a list of tags.
Returns
-------
nodes : pandas.DataFrame
    Will have 'lat' and 'lon' columns, plus other columns for the
    tags associated with the node (these will vary based on the query).
    Index will be the OSM node IDs.
File:      ~/mambaforge/envs/musa-550-fall-2023/lib/python3.10/site-packages/pandana/loaders/osm.py
Type:      function

Get the bounding box for Northern Liberties / Fishtown:

boundary = center_city_outline.bounds
boundary
(-75.193582452986, 39.9286257450627, -75.1259307965391, 39.9738724134056)
[lng_min, lat_min, lng_max, lat_max] = boundary
# query OSM
poi_df = osm.node_query(lat_min, lng_min, lat_max, lng_max)

# remove missing data
poi_df = poi_df.dropna(subset=["amenity"])
poi_df.head()
lat lon railway light_rail name network operator public_transport wheelchair highway traffic_signals old_ref ref noref traffic_signals:direction direction traffic_calming crossing crossing:markings tactile_paving stop noexit crossing:barrier barrier crossing:island disused:railway crossing_ref supervised railway:signal:direction ele gnis:feature_id place wikidata wikipedia alt_name gnis:Class gnis:County gnis:County_num gnis:ST_alpha gnis:ST_num import_uuid is_in name:en name:zh amenity brand brand:wikidata brand:wikipedia operator:wikidata operator:wikipedia short_name addr:city addr:housenumber addr:postcode addr:state addr:street contact:website cuisine official_name opening_hours phone takeaway shop website ferry building addr:housename healthcare internet_access internet_access:ssid brewery description gnis:county_id gnis:created gnis:state_id historic:amenity note old_name craft microbrewery restaurant leisure sport man_made tower:type gnis:edited operator:short operator:type check_date emergency healthcare:speciality railway:position train artwork_type historic tourism atm information artist_name material attraction office bench bus covered network:wikidata shelter memorial gnis:county_name gnis:import_uuid gnis:reviewed comment historic:tourism aeroway gnis:feature_type addr:country platforms station subway kerb junction iata railway:ref railway:switch:local_operated railway:signal:position addr:unit internet_access:fee crossing:light start_date subject:wikidata artwork_subject image statue tram contact:facebook email reservation website:menu colour parking designation not:brand:wikidata entrance denomination religion screen delivery diet:vegan outdoor_seating payment:cash payment:coins air_conditioning contact:phone indoor_seating smoking architect disused:amenity contact:instagram network:wikipedia collection_times male female dispensing name:de drive_through diet:vegetarian fax bar service:bicycle:pump service:bicycle:repair service:bicycle:retail toilets:wheelchair route_ref capacity source:pkey power access level museum name:he fuel:biodiesel fuel:biogas fuel:cng fuel:diesel fuel:e10 fuel:e85 fuel:electricity collection_times:signed ref:signed check_date:collection_times clothes addr:full branch name:ja operator:en fair_trade organic disused:shop fixme artist:wikidata inscription:url name:ga contact:email payment:bitcoin source:name phone:mnemonic disused:brand disused:brand:wikidata disused:brand:wikipedia disused:dispensing disused:drive_through disused:healthcare disused:opening_hours diet:pescetarian lgbtq payment:credit_cards payment:debit_cards drink:club-mate fare_zone toilets toilets:access building:levels is_in:state_code population farm_boxes compost addr:place social_facility check_date:opening_hours source:cuisine social_facility:for demolished:amenity demolished:opening_hours demolished:phone demolished:social_facility maxheight access:delivery wheelchair:description wheelchair:description:en beauty elevation fee park_ride layer height name:es service:bicycle:chain_tool natural name:fr name:signed bin lit departures_board denotation facebook currency:USD drink:coca-cola drink:coke drink:cola drink:cola_zero drink:soda drink:water vending opening_hours:kitchen bicycle_rental disused:leisure year_of_construction name:ru toilets:unisex toilets:disposal unisex kitchen_hours currency:XBT animal owner button_operated traffic_signals:sound traffic_signals:vibration source:lgbtq service:bicycle:rental service:bicycle:second_hand bicycle horse motor_vehicle bottle surface lamp_type theatre:genre service:bicycle:tools bicycle_parking ref:retrofitness leaf_cycle leaf_type capital loc_name name:ar name:azb name:be name:bn name:ca name:cs name:el name:fa name:grc name:hi name:it name:kn name:ko name:lv name:moh name:oc name:ono name:pa name:pl name:pt name:sr name:ta name:te name:tr name:uk name:ur name:zh-Hans name:zh-Hant population:date source:name:oc source:population payment:cheque advertising payment:american_express payment:mastercard payment:visa backrest fire_hydrant:position fire_hydrant:type club playground date display faces studio seamark:type amenity_1 payment:venmo self_service payment:cards payment:contactless payment:notes fountain camera:direction camera:mount camera:type surveillance surveillance:type manhole drink:beer recycling_type addr:block_number seats brand:type end_date subject:wikipedia type authority marker_date historic:name parcel_locker:type parcel_mail_in consulate country diplomatic target dog recycling:beverage_cartons recycling:cans recycling:glass_bottles recycling:paper recycling:plastic recycling:plastic_bottles recycling:plastic_packaging postal_code changing_table portable toilets:handwashing toilets:position locked payment:discover_card flag:name flag:type flag:wikidata subject flag:colour foot communication:mobile_phone school dance:style dance:teaching waste landuse military_service generator:method generator:output:electricity generator:source generator:type payment:cash_app seating street_vendor books gender inscription hiking support twitter door smoothness contact:flickr contact:mastodon contact:twitter indoor name:etymology:wikidata payment:paypal min_age was:amenity Business network:short mimics source:url disused opening_hours:signed location water_source drinking_water fridge wikimedia_commons ramp:wheelchair food generator:output:hot_water not:network:wikidata bridge:support opening_hours:url payment:lightning payment:lightning_contactless payment:onchain fishing couplings government self_checkout flickr disused:payment:cash disused:payment:contactless disused:payment:credit_cards disused:payment:debit_cards disused:phone disused:ref delivery:partner internet_access:password surveillance:zone post_box:type fire_mains fire_sprinkler bonnet:colour lamp_mount openplaques:id description:en military memorial:website ref:hmdb post_office service:bicycle:sales service:bicycle:service diet:gluten_free addr:door community_centre:for community_centre cycleway name:etymology
id
274216093 39.957640 -75.191254 NaN NaN Citibank NaN Citibank NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN atm Citibank Q857063 en:Citibank Q857063 en:Citibank Citi NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
274217596 39.953015 -75.192289 NaN NaN Starbucks NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN cafe Starbucks Q37158 en:Starbucks NaN NaN NaN Philadelphia 3401 19104 PA Walnut Street https://www.starbucks.com/store-locator/store/... coffee_shop Starbucks Coffee Mo-Fr 05:30-24:00; Sa,Su 06:00-24:00 215-387-1914 yes NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
313440966 39.963935 -75.166939 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN car_sharing NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
313440968 39.963978 -75.170407 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN car_sharing NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
326519551 39.944261 -75.132616 NaN NaN Camden RiverLink Ferry Landing NaN NaN station NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ferry_terminal NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN https://www.delawareriverwaterfront.com/places... yes NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
len(poi_df)
2383
poi_df[["lat", "lon", "amenity"]].head(10)
lat lon amenity
id
274216093 39.957640 -75.191254 atm
274217596 39.953015 -75.192289 cafe
313440966 39.963935 -75.166939 car_sharing
313440968 39.963978 -75.170407 car_sharing
326519551 39.944261 -75.132616 ferry_terminal
333786044 39.940858 -75.158928 restaurant
333786095 39.941924 -75.157357 cafe
333786448 39.942642 -75.157958 bank
333786774 39.943102 -75.160030 pharmacy
343293716 39.960440 -75.159770 cafe

Explore the amenities in this region

For the full list of amenities, see the OSM Wikipedia

chart = (
    alt.Chart(poi_df)
    .mark_bar()
    .encode(y=alt.Y("amenity", sort="-x"), x="count()", tooltip=["amenity", "count()"])
)

chart
/Users/nhand/mambaforge/envs/musa-550-fall-2023/lib/python3.10/site-packages/altair/utils/schemapi.py:353: DeprecationWarning: jsonschema.RefResolver is deprecated as of v4.18.0, in favor of the https://github.com/python-jsonschema/referencing library, which provides more compliant referencing behavior as well as more flexible APIs for customization. A future release will remove RefResolver. Please file a feature request (on referencing) if you are missing an API for the kind of customization you need.
  resolver = jsonschema.RefResolver.from_schema(root or schema)
/Users/nhand/mambaforge/envs/musa-550-fall-2023/lib/python3.10/site-packages/altair/utils/schemapi.py:118: DeprecationWarning: jsonschema.RefResolver is deprecated as of v4.18.0, in favor of the https://github.com/python-jsonschema/referencing library, which provides more compliant referencing behavior as well as more flexible APIs for customization. A future release will remove RefResolver. Please file a feature request (on referencing) if you are missing an API for the kind of customization you need.
  resolver = jsonschema.RefResolver.from_schema(rootschema)

Step 2: Create a Pandana network

  • Key function: pdna_network_from_bbox()
  • It takes a bounding box and returns the OSM network within that region.
  • Multiple network types: ‘walk’ and ‘drive’
net = osm.pdna_network_from_bbox(
    lat_min, lng_min, lat_max, lng_max, network_type="walk"
)
Requesting network data within bounding box from Overpass API in 1 request(s)
Posting to http://www.overpass-api.de/api/interpreter with timeout=180, "{'data': '[out:json][timeout:180];(way["highway"]["highway"!~"motor|proposed|construction|abandoned|platform|raceway"]["foot"!~"no"]["pedestrians"!~"no"](39.92862575,-75.19358245,39.97387241,-75.12593080);>;);out;'}"
Downloaded 7,197.3KB from www.overpass-api.de in 1.15 seconds
Downloaded OSM network data within bounding box from Overpass API in 1 request(s) and 1.23 seconds
Returning OSM data with 37,969 nodes and 11,923 ways...
Edge node pairs completed. Took 3.51 seconds
Returning processed graph with 17,584 nodes and 26,363 edges...
Completed OSM data download and Pandana node and edge table creation in 4.99 seconds
Generating contraction hierarchies with 10 threads.
Setting CH node vector of size 17584
Setting CH edge vector of size 26583
Range graph removed 992 edges of 53166
. 10% . 20% . 30% . 40% . 50% . 60% . 70% . 80% . 90% . 100%

Step 3: Tell the network the location of amenities

Key function: network.set_pois()

  • Today, we’ll explore these four amenities: “restaurant”, “bar”, “school”, “car_sharing”
  • IMPORTANT: if you want to explore other amenities, you’ll need to run the code below for your amenities of interest
# sensible defaults
max_distance = 2000  # in meters
num_pois = 10  # only need the 10 nearest POI to each point in the network


AMENITIES = ["restaurant", "bar", "school", "car_sharing"]
for amenity in AMENITIES:
    # get the subset of amenities for this type
    pois_subset = poi_df[poi_df["amenity"] == amenity]

    # set the POI, using the longitude and latitude of POI
    net.set_pois(
        amenity, max_distance, num_pois, pois_subset["lon"], pois_subset["lat"]
    )
# keyword arguments to pass for the matplotlib figure
bbox_aspect_ratio = (lat_max - lat_min) / (lng_max - lng_min)
fig_kwargs = {"facecolor": "w", "figsize": (10, 10 * bbox_aspect_ratio)}

# keyword arguments to pass for scatter plots
plot_kwargs = {"s": 20, "alpha": 0.9, "cmap": "viridis_r", "edgecolor": "none"}

Step 4: Plot the walking distance to the nearest POI

For every point on the network, find the nth nearest POI, calculate the distance, and color that point according to the distance.

  1. Use network.nearest_poi() to get distances from nodes to nearest POIs
  2. Merge coordinates of network nodes with distances to nearest POIs
  3. Plot the node coordinates, colored by distance to nth nearest POI

4.1 Use network.nearest_poi() to get distances from nodes to nearest POIs

amenity = "bar"
access = net.nearest_pois(distance=2000, category=amenity, num_pois=num_pois)
access.head(n=20)
1 2 3 4 5 6 7 8 9 10
id
103327043 1752.093018 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103332711 988.283020 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103332730 670.846008 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103333406 597.692993 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103333412 623.888977 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103333415 622.456970 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103338754 712.594971 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103338757 744.122986 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103338759 770.111023 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103338773 877.939026 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103346474 84.362999 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103346591 884.025024 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103346606 903.419006 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103353253 239.848007 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103356072 290.412994 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103356074 362.723999 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103356075 407.182007 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103363102 1938.394043 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103369979 2000.000000 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103369980 2000.000000 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0

4.2 Merge coordinates of network nodes with distances to nearest POIs

net.nodes_df.head()
x y
id
103327043 -75.128666 39.934488
103332711 -75.128062 39.939224
103332730 -75.129329 39.941869
103333406 -75.130257 39.943351
103333412 -75.130332 39.943123
access.head()
1 2 3 4 5 6 7 8 9 10
id
103327043 1752.093018 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103332711 988.283020 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103332730 670.846008 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103333406 597.692993 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103333412 623.888977 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
# Merge the nodes and the distance to POIs
nodes = pd.merge(net.nodes_df, access, left_index=True, right_index=True)

# Make into a geodataframe
nodes = gpd.GeoDataFrame(
    nodes, geometry=gpd.points_from_xy(nodes["x"], nodes["y"]), crs="EPSG:4326"
)
nodes.head()
x y 1 2 3 4 5 6 7 8 9 10 geometry
id
103327043 -75.128666 39.934488 1752.093018 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 POINT (-75.12867 39.93449)
103332711 -75.128062 39.939224 988.283020 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 POINT (-75.12806 39.93922)
103332730 -75.129329 39.941869 670.846008 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 POINT (-75.12933 39.94187)
103333406 -75.130257 39.943351 597.692993 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 POINT (-75.13026 39.94335)
103333412 -75.130332 39.943123 623.888977 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 POINT (-75.13033 39.94312)

4.3 And now plot it!

Let’s define a function to do this for us, since we’ll repeat this plot multiple times

def plot_walking_distance(net, amenity, distance=1000, n=1):
    """
    Plot the walking distance to the specified amenity
    """
    from mpl_toolkits.axes_grid1 import make_axes_locatable

    # subset of POI
    poi_subset = poi_df[poi_df["amenity"] == amenity]

    # get the distances to nearest num_pois POI
    access = net.nearest_pois(distance=1000, category=amenity, num_pois=num_pois)

    # merge node positions and distances to nearest PO
    nodes = pd.merge(net.nodes_df, access, left_index=True, right_index=True)
    nodes = gpd.GeoDataFrame(
        nodes, geometry=gpd.points_from_xy(nodes["x"], nodes["y"]), crs="EPSG:4326"
    )

    # Create the figure
    fig, ax = plt.subplots(figsize=(10, 10))
    divider = make_axes_locatable(ax)
    cax = divider.append_axes("right", size="5%", pad=0.1)

    # plot the distance to the nth nearest amenity
    ax = nodes.plot(ax=ax, cax=cax, column=nodes[n], legend=True, **plot_kwargs)

    # add the amenities as stars
    for i, row in poi_subset.iterrows():
        ax.scatter(row["lon"], row["lat"], color="red", s=100, marker="*")

    # format
    ax.set_facecolor("black")
    ax.figure.set_size_inches(fig_kwargs["figsize"])

    # set extent
    [xmin, ymin, xmax, ymax] = nodes.geometry.total_bounds
    ax.set_xlim(xmin, xmax)
    ax.set_ylim(ymin, ymax)

    return ax

Evaluating amenity choice

The difference between maps to the nearest amenity and for example, the 5th nearest amenity tells us about the options consumers have

Example: bars

ax = plot_walking_distance(net, "bar", n=1)
ax.set_title("Walking distance to the nearest bar", fontsize=18);

ax = plot_walking_distance(net, "bar", n=3)
ax.set_title("Walking distance to the 3rd nearest bar", fontsize=18);

Example: schools

ax = plot_walking_distance(net, "school", n=1)
ax.set_title("Walking distance to the nearest school", fontsize=18);

ax = plot_walking_distance(net, "school", n=3)
ax.set_title("Walking distance to the 3rd nearest school", fontsize=18);

Example: restaurants

ax = plot_walking_distance(net, "restaurant", n=1)
ax.set_title("Walking distance to the nearest restaurant", fontsize=18);

ax = plot_walking_distance(net, "restaurant", n=5)
ax.set_title("Walking distance to the 5th nearest restaurant", fontsize=18);

Example: car sharing

ax = plot_walking_distance(net, "car_sharing", n=1)
ax.set_title("Walking distance to the nearest car sharing", fontsize=18);

ax = plot_walking_distance(net, "car_sharing", n=10)
ax.set_title("Walking distance to the 10th nearest car sharing", fontsize=18);

At-home exercise: Explore amenities in the neighborhood of your choice

Many, many more amenities are logged throughout the city. Pick your favorite neighborhood and explore.

See this page for the full list of amenities.

Final project idea: With this kind of analysis, you can look at amenity-based influence in housing, neighborhood selection, etc. or something similar to the Walk Score.

Content 2023 by Nick Hand, Quarto layout adapted from Andrew Heiss’s Data Visualization with R course
All content licensed under a Creative Commons Attribution-NonCommercial 4.0 International license (CC BY-NC 4.0)
 
Made with and Quarto
View the source at GitHub